const fs = require('fs')
const file = fs.readFileSync('./README.md') // 需要等待完成
console.log(file)
const arr = []
for (let i = 2; i <= 99999999; i+=2) {
arr.push(i)
}
console.log(arr)
程式碼需要再讀去檔案的地方等待幾秒才能執行下一行動作,fs.readFileSync阻擋了後面程式的執行,這個method就是阻塞(blocking)的,因為程式的執行會一直 block 在這裡直到他執行完畢。
流程圖 :
const fs = require('fs')
// 定義讀取檔案完成以後,要執行的 function
function readFileFinished(err, data) {
if (err)
{
console.log(err)
}
else
{
console.log(data)
}
}
// 讀取檔案,第二個參數是 callback function
fs.readFile('./README.md', readFileFinished);
on-blocking 的 method 執行完 function 以後就可以直接跳下一行了,檔案讀取完畢以後會把結果傳進 callback function,放在上面的程式碼中,當執行fs.readFile後,會將他先放到一個地方(後面會解釋),讓程式能夠先執行後面的程式,等到fs.readFile讀取完畢後會將讀取到的data放到callback funciton中。
流程圖 :
基本上同步(synchronous)與非同步(asynchronous)可以等於阻塞(blocking)與非阻塞(non-blocking)
1.同步(synchronous)代表執行時程式會卡在那一行,直到有結果為止。
2.非同步(asynchronous)代表執行時不會卡住,但執行結果不會放在回傳值,而是需要透過回呼函式(callback function)來接收結果
在瀏覽器中使用同步會阻塞後面的執行,若API Server需要讀取10秒,整個JavaScript引擎就必須等待10秒才能做下面的動作,會造成整個瀏覽器無法動作凍結10秒,若要避免此狀況就必須讓需要等待很久的JavaScript變成非同步並讓callback Function來接收結果。
有三種非同步的寫法 :
//1. 宣告function
function handleResponst() {
console.log(response)
}
getAPIResponse(handleResponst)
//2. 匿名函式
getAPIResponse(function(err, response) {
console.log(response)
})
//3. 箭頭函式
getAPIResponse((err, response) => {
console.log(response)
})
callback function 的意思:「當某事發生的時候,就使用這個 function 」,雖然乍看之下很陌生但是卻常常再用。
HTML :
<button id="btn">Click</button>
JavaScript :
const button = document.getElementById("btn");
button.addEventListener("click",handleClick);
function handleClick(){
alert("Click");
}
「當某事(onclick觸發)發生後,會呼叫handleClick這個function」,handleClick就是個 callback function
*使用callback function時要注意傳進去的callback function是個 "function" 而不是function的結果,所以不能使用 " function() "
//錯誤用法
const button = document.getElementById("btn");
button.addEventListener("click",handleClick());
function handleClick(){
alert("Click");
}
Callback 的 error first會習慣放在第一個,因為錯誤只有一個(讀取失敗,沒有這個檔案...)但是回傳值卻會有很多個,若把err放在最後一個就必須把前面的回傳值都填入,這樣並不方便,所以將err放在第一個位置就可以控制需要幾個回傳值。
參考文章 :
JavaScript 中的同步與非同步(上):先成為 callback 大師吧!